#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)13   1.14.1.16   src/csm/dms/cmds/csmconfig.perl, dms, csm_rameh, rameh0431a 7/2/04 13:54:32

use strict;
use locale;

BEGIN
{

    # this enables us to redirect where it looks for other CSM files during development
    $::csmroot = $ENV{'CSM_ROOT'} ? $ENV{'CSM_ROOT'} : '/opt/csm';
    $::csmpm   = "$::csmroot/pm";
    $::csmbin  = "$::csmroot/bin";
}
use lib $::csmpm;
use Getopt::Std;
require NodeUtils;
require CSMDefs;
require InstallUtils;
require InstallKRB5Utils;

# get the definitions we need for this command
#    in this case get_OSDefs uses the attrs of the management
#    server to identify the correct definitions
%::myOSDefs = InstallUtils->get_OSDefs();
my $CSMKEYTAB = "/var/ct/IW/sec/krb5/csm/k5keytabs/ctsrcmdp";

#set LD_ASSUME_KERNEL if running on a RH EL 3 machine
my $rh_relfile = "/etc/redhat-release";
my $rh_vers    = '^Red Hat Enterprise Linux .* release 3 (.*)$';
if (-f $rh_relfile)
{
    `/bin/grep \"$rh_vers\" $rh_relfile > /dev/null 2>&1`;
    my $exit = $? >> 8;
    if ($exit == 0)
    {
        $ENV{'LD_ASSUME_KERNEL'} = "2.4.19";
    }
}

#nlstodo:  add these to nodecmds.msg.  Also add -Z to usage and make -L arg optional.
#$::MSGS = {
#    IMsgBACKUP      => 'Backing up file %1$s to %2$s\n',
#    EMsgALREADY_TAB =>
#      'A try and buy license is already installed.  Run csmconfig without arguments to see the expiration date of the license.\n',
#    EMsgALREADY_FULL =>
#      'A full license is already installed.  Not installing the try and buy license.\n',
#    EMsgNOT_ACCEPTED =>
#      'License agreement not accepted - can not install license key.\n',
#    EMsgACCEPTED => 'The license agreement has been accepted.\n'
#    };

#nlstodo: add -d option to IMsgCsmconfigUsage
#nls -- done

# For the usage, see nodecmds.msg
sub usage
{
    NodeUtils->message('I', 'IMsgCsmconfigUsage');
    exit(scalar(@_) ? $_[0] : 1);
}

$::MSGCAT     = 'nodecmds.cat';
$::MSGMAPPATH = "$::csmroot/msgmaps";
$::MSGSET     = 'csmconfig'
  ;    # setting this explicitly so it will work with the old dmsctrl link

# check if the command is running on management server
if (!NodeUtils->isMgmtSvr())
{
     #my $program     = NodeUtils->programName();
     NodeUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH, 'csminstall',
                                  'E2', 'EMsgNOManagementServer');

}

# Parse the cmd line args and check them
if (!getopts('hvVp:u:m:s:r:R:K:Ld:Z:c')) { &usage; }
if ($::opt_h) { &usage(0); }
my $setflags =
  defined($::opt_u) + defined($::opt_m) + defined($::opt_s) + defined($::opt_r)
  + defined($::opt_R) + defined($::opt_K) + defined($::opt_p);
if (
    (
     defined($::opt_V) + defined($::opt_L) + defined($::opt_d) +
     defined($::opt_Z) +
     ($setflags > 0 || (scalar(@ARGV) > 0 && !defined($::opt_L)))
    ) > 1
  )
{
    &usage;
}

$::VERBOSE = $::opt_v;
$ENV{'CT_MANAGEMENT_SCOPE'} =
  1;    # set local scope because we only want the local DmsCtrl class

#my $rc=0;
if ($::opt_V)    # display CSM version
{
    my $version = InstallUtils->get_CSMVersion('csm.server', 1);
    if (!defined($version))
    {
        exit 2;
    }            # the above function already displayed an error msg
    print "$version\n";
}

# Install A License Key File

elsif (defined($::opt_L)) {

  # Possible Flows
  #
  # Was a key provided?
  #   Yes:
  #     Was it a tab key?
  #       Yes:
  #         Was a key provided previously?
  #           Yes:
  #             Was it a tab key?
  #               Yes: *CASE 1* can not install tab key over tab key
  #               No:  *CASE 2* can not install tab key over full key
  #           No: *CASE 3* process tab key
  #       No:
  #         Was a key provided previously?
  #           Yes:
  #             Was it a tab key?
  #               Yes: *CASE 4* process full key - back up previous tab key
  #               No:
  #                 Is key provided same as previous accepted key?
  #                   Yes: *CASE 5* process full key
  #                   No:  *CASE 6* process full key - back up previous full key
  #           No: *CASE 7* process full key
  #   No:
  #     Was a key provided previously?
  #       Yes:
  #         Was it a tab key?
  #           Yes: *CASE 8* reprocess old tab key
  #           No:  *CASE 9* reprocess old full key
  #       No: *CASE 10* process default tab key

  # Variables Used

  my $name_key_given;
  my $key_given;
  my $temp;
  my $tab_key_given;
  my $key_accepted_before;
  my $tab_key_accepted_before;
  my $key;
  my $tab_key;
  my $key_version;

  # Information gathering about key provided and previously existing keys
 
  # Was a key given on the command line?
  # command syntax is csmconfig -L <key>
  # check if key file name given and readable
  if (scalar(@ARGV)) {
    # A key was given on the command line.
    $name_key_given = $ARGV[0];
    # Is it readable?
    if (!(-r $name_key_given)) {
      # File not readable
      NodeUtils->message('E1', 'EMsgBAD_KEYFILE', $name_key_given);
      $key_given = 0;
    }
    else {
      # It is readable!
      $key_given = 1;
    }
  }
  else {
    # A key was not given on the command line.
    $key_given = 0;
  }

  # If a key was provided, what kind of key is it?
  # we can see if it is a try and buy by grepping for it in the file
  if ($key_given) {
    $temp = NodeUtils->runcmd("/bin/grep TryAndBuy $name_key_given");
    if ($temp =~ /TryAndBuy\s*=\s*Yes/) {
      $tab_key_given = 1;
    }
    else {
      $tab_key_given = 0;
    }
  }
  else {
    $tab_key_given = 0;
  }

  # Was a key ever accepted in the past?
  # if a full key was previously accepted, it would be located at
  # /var/opt/csm/lic/csmlum.lic
  # if a tab key was previously accepted, it would be located at
  # /var/opt/csm/lic/csmlum.tab
  if ((-f "/var/opt/csm/lic/csmlum.lic") || (-f "/var/opt/csm/lic/csmlum.tab")) {
    $key_accepted_before = 1;
  }
  else {
    $key_accepted_before = 0;
  }

  # If a key was accepted, what kind of key was it?
  # we can tell based on what files exist in the lic directory
  # a csmlim.lic and csmlum.tab should never exist at the same time
  if ($key_accepted_before) {
    if (-f "/var/opt/csm/lic/csmlum.tab") {
      $tab_key_accepted_before = 1;
    }
    else {
      $tab_key_accepted_before = 0;
    }
  }
  else {
    $tab_key_accepted_before = 0;
  }

  # Figure out how to process keys

  if ($key_given) {
    if ($tab_key_given) {
      if ($key_accepted_before) {
        if ($tab_key_accepted_before) {
          # CASE 1
          # tab key was given, but tab key was previously accepted
          # cannot install tab key over another tab key
          NodeUtils->message('W2', 'EMsgALREADY_TAB');
        }
        else {
          # CASE 2
          # tab key was given, but full key was previously accepted
          # cannot install tab key over a full key
          NodeUtils->message('W2', 'EMsgALREADY_FULL');
        }
      }
      else {
        # CASE 3
        # tab key given, no keys accepted before
        $key = $name_key_given;
        $tab_key = $tab_key_given;
      }
    }
    else {
      # CASES 4, 5, 6, 7
      # full key was given
      # alway process full key regardless of what was accepted before
      $key = $name_key_given;
      $tab_key = $tab_key_given;
    }
  }
  else {
    if ($key_accepted_before) {
      if ($tab_key_accepted_before) {
        # CASE 8
        # a key was not given, but a tab key was accepted previously
        # we will continue to use that one
        $key = "/var/opt/csm/lic/csmlum.tab";
        $tab_key = 1;
      }
      else {
        # CASE 9
        # a key was not given, but a full key was accepted previously
        # we will continue to use that one
        $key = "/var/opt/csm/lic/csmlum.lic";
        $tab_key = 0;
      }
    }
    else {
      # CASE 10
      # a key was not given, and none have been accepted previously
      # we will use the default try and buy license
      $key = "/var/opt/csm/lic/default";
      $tab_key = 1;
    }
  }

  # Process keys

  # Display license agreement
  # display full or try and buy aggreement based on the key we are using
  &displayLicenseAgreement($tab_key);

  # if the license directory does not exist, create it
  if (!(-d "/var/opt/csm/lic")) { NodeUtils->runcmd("/bin/mkdir -p /var/opt/csm/lic"); }

  # Backup previous license files

  # backup previous nodelock file, if necessary
  # regenerate the nodelock file every time (the refresh of dmsrm regenerates the file)
  if (-f "/var/opt/csm/lic/nodelock") {
    rename("/var/opt/csm/lic/nodelock", "/var/opt/csm/lic/nodelock.backup")
      or NodeUtils->messageFromCat(
        $::MSGCAT,                         $::MSGMAPPATH,
        'NodeUtils',                       'E' . $! / 1,
        'EMsgCMD_FAILED',                  $! / 1,
        "rename(/var/opt/csm/lic/nodelock, /var/opt/csm/lic/nodelock.backup)", $!);
  }

  # backup previous tab file, if necessary
  if (-f "/var/opt/csm/lic/csmlum.tab") {
    rename("/var/opt/csm/lic/csmlum.tab", "/var/opt/csm/lic/csmlum.tab.backup")
      or NodeUtils->messageFromCat(
         $::MSGCAT,                         $::MSGMAPPATH,
         'NodeUtils',                       'E' . $! / 1,
         'EMsgCMD_FAILED',                  $! / 1,
         "rename(/var/opt/csm/lic/csmlum.tab, /var/opt/csm/lic/csmlum.tab.backup)", $!);
  }

  # backup previous lic file, if necessary
  if (-f "/var/opt/csm/lic/csmlum.lic") {
    rename("/var/opt/csm/lic/csmlum.lic", "/var/opt/csm/lic/csmlum.lic.backup")
      or NodeUtils->messageFromCat(
        $::MSGCAT,                         $::MSGMAPPATH,
        'NodeUtils',                       'E' . $! / 1,
        'EMsgCMD_FAILED',                  $! / 1,
        "rename(/var/opt/csm/lic/csmlum.lic, /var/opt/csm/lic/csmlum.lic.backup)", $!);
  }

  # if key we are using was previously accepted, rename it to now point to the backup
  if ($key =~ /\/var\/opt\/csm\/lic\/csmlum.tab/) {
    $key = "/var/opt/csm/lic/csmlum.tab.backup";
  }
  if ($key =~ /\/var\/opt\/csm\/lic\/csmlum.lic/) {
    $key = "/var/opt/csm/lic/csmlum.lic.backup";
  }

  # copy the tab or lic file to the location DMSRM needs it in
  if ($tab_key) {
    NodeUtils->runcmd("/bin/cp $key /var/opt/csm/lic/csmlum.tab");
  }
  else {
    NodeUtils->runcmd("/bin/cp $key /var/opt/csm/lic/csmlum.lic");
  }

  # Send DMSRM the product version in the LUM file.
  # DMSRM will accept 1.3 or 1.4 in CSM 1.4*
  $key_version = NodeUtils->runcmd("/bin/grep ProductVersion $key");
  $key_version =~ s/ProductVersion=//;
  NodeUtils->runrmccmd('chrsrc-api','-i',qq(-s IBM.DmsCtrl::::LicenseProductVersion::$key_version));

  # Refresh DmsCtrl so that it picks up the ECF file and creates the
  # nodelock file
  NodeUtils->runrmccmd('refrsrc-api', '-c IBM.DmsCtrl');

}

elsif (defined($::opt_Z))    # display license agreement
{
    &displayLicenseAgreement($::opt_Z);
}


elsif (defined($::opt_d))    # display just one attr
{
    if ($::opt_d =~ /Sensitivity/ || $::opt_d =~ /Frequency/)
    {
        $::opt_d =~ s/Heartbeat//;
    }
    my $outref =
      NodeUtils->runrmccmd('lsrsrc-api', '', "-s IBM.DmsCtrl::::$::opt_d");
    print "$$outref[0]\n";
}

elsif ($setflags || scalar(@ARGV) > 0)    # set 1 or more of the values
{
    my %attrs;

    # 1st process the attr=val pairs
    foreach my $a (@ARGV)
    {

        # Note: we allow a null value
        my ($at, $val) = $a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/;
        if (!defined($at))
        {
            NodeUtils->messageFromCat($::MSGCAT, $::MSGMAPPATH, 'createnode',
                                      'E1', 'EMsgBAD_ATTR_VAL_FORM');
        }
        if ($at =~ /Sensitivity/ || $at =~ /Frequency/)
        {
            $at =~ s/Heartbeat//;
        }
        elsif ($at =~ /PowerStatusMode/)
        {
            if ($val =~ /Mixed|0/i)
            {
                $attrs{$at} = 0;
            }
            elsif ($val =~ /Events|1/i)
            {
                $attrs{$at} = 1;
            }
            elsif ($val =~ /Polling|2/i)
            {
                $attrs{$at} = 2;
            }
            elsif ($val =~ /None|3/i)
            {
                $attrs{$at} = 3;
            }
            else
            {
                NodeUtils->message('E1', 'EMsgBAD_P_VALUE', 'PowerStatusMode');
            }

        }
        if (!defined($::opt_p))
        {
            $attrs{$at} = $val;
        }
    }

    # Now process specific flags
    if (defined($::opt_u)) { $attrs{'AddUnrecognizedNodes'} = $::opt_u; }
    if (defined($::opt_R)) { $attrs{'SetupRemoteShell'}     = $::opt_R; }
    if (defined($::opt_K)) { $attrs{'SetupKRB5'}            = $::opt_K; }
    if (defined($::opt_r)) { $attrs{'RemoteShell'}          = $::opt_r; }
    if (defined($::opt_m)) { $attrs{'ClusterTM'}            = $::opt_m; }
    if (defined($::opt_s)) { $attrs{'ClusterSNum'}          = $::opt_s; }
    if (defined($::opt_p)) { $attrs{'PowerStatusMode'}      = $::opt_p; }

    # Now check the values
    my $r;    # this reduces the # of hash lookups
    if (defined($r = $attrs{'AddUnrecognizedNodes'}))
    {
        if    ($r =~ /yes|1/i) { $attrs{'AddUnrecognizedNodes'} = 1; }
        elsif ($r =~ /no|0/i)  { $attrs{'AddUnrecognizedNodes'} = 0; }
        else
        {
            NodeUtils->message('E1', 'EMsgBAD_U_VALUE', 'AddUnrecognizedNodes');
        }
    }
    if (defined($r = $attrs{'SetupRemoteShell'}))
    {
        if    ($r =~ /yes|1/i) { $attrs{'SetupRemoteShell'} = 1; }
        elsif ($r =~ /no|0/i)  { $attrs{'SetupRemoteShell'} = 0; }
        else
        {
            NodeUtils->message('E1', 'EMsgBAD_U_VALUE', 'SetupRemoteShell');
        }
    }
    if (defined($r = $attrs{'SetupKRB5'}))
    {
        if (   ($r ne "0")
            && ($r ne "1")
            && ($r ne "2")
            && ($r ne "3")
            && ($r ne "4")
            && ($r ne "5")
            && ($r ne "6")
            && ($r ne "7")
            && ($r ne "8")
            && ($r ne "9")
            && ($r ne "10")
            && ($r ne "11")
            && ($r ne "12")
            && ($r ne "13")
            && ($r ne "14")
            && ($r ne "15"))
        {
            NodeUtils->message('E1', 'EMsgBAD_K_VALUE', 'SetupKRB5');
        }
        if ($r != 0)
        {    # request to  setup  KRB5
            if ($< == 0)
            {    # I am root
                my $rc;
                my $distro = NodeUtils->distribution();
                if ($distro =~ /SuSE/ || $distro =~ /SLES/)
                {    # if SUSE/SLES
                    $attrs{'SetupKRB5'} = 4;    # default to 4
                                                # Format the principal name
                    my $msname1 = NodeUtils->getRSCThostname;
                    my $msname  = lc($msname1);
                    if (
                        (-e "$CSMKEYTAB.$msname.keytab")    # exists then ok
                        && !(-z "$CSMKEYTAB.$msname.keytab")
                      )
                    {
                        $rc = 0;
                    }
                    else
                    {    # tell them they must set up Kerberos
                        NodeUtils->message(
                              'I',                'IMsgBAD_K_VALUE_UNSUPPORTED',
                              "ctsrcmdp.$msname", "$CSMKEYTAB.$msname.keytab");
                    }
                }
                else
                {        # not SUSE we can do some setup
                    if (   ($r == 1)
                        || ($r == 3)
                        || ($r == 5)
                        || ($r == 7)
                        || ($r == 9)
                        || ($r == 11)
                        || ($r == 13)
                        || ($r == 15))
                    {    # request to setup server
                        if (NodeUtils->isAIX())
                        {    # only valid on AIX
                            $rc = InstallKRB5Utils->setupKRB5server;
                            if ($rc != 0)
                            {
                                NodeUtils->message('E1', 'EMsg_KRB5_Setup_Err');
                            }
                        }
                        else
                        {    # setup server only valid on AIX MS
                            NodeUtils->message('E1', 'EMsgKRB5InvalidRequest');

                        }
                    }    # end request setup server
                    if (   ($r == 4)
                        || ($r == 5)
                        || ($r == 6)
                        || ($r == 7)
                        || ($r == 8)
                        || ($r == 9)
                        || ($r == 10)
                        || ($r == 11)
                        || ($r == 12)
                        || ($r == 13)
                        || ($r == 14)
                        || ($r == 15))
                    {    # request to setup principal
                        my @attrlist = ($r);
                        my @empty_array;    # get all managed nodes
                        $rc =
                          InstallKRB5Utils->setupKRB5rcmdprincs(\@attrlist,
                                                                \@empty_array);
                        if ($rc != 0)
                        {
                            NodeUtils->message('E1', 'EMsg_KRB5_Setup_Err');
                        }
                    }    # end request setup principals
                }    # end SUSE
            }
            else
            {        # not root
                NodeUtils->message('E1', 'EMsgKRB5NonRoot');

            }
        }    # end !=0
    }    # end SetupKRB5
    if (defined($r = $attrs{'RemoteShell'}))
    {
        if (!(-x $r)) { NodeUtils->message('E1', 'EMsgBAD_SHELL', $r); }
    }
    if (defined($r = $attrs{'ClusterTM'}))
    {
        if (!($r =~ /^\s*\d{4}-\d{3}\s*$/))
        {
            NodeUtils->message('E1', 'EMsgBAD_MODEL', $r);
        }
    }
    if (defined($r = $attrs{'PowerStatusMode'}))
    {
        if    ($r =~ /Mixed|0/i)   { $attrs{'PowerStatusMode'} = 0; }
        elsif ($r =~ /Events|1/i)  { $attrs{'PowerStatusMode'} = 1; }
        elsif ($r =~ /Polling|2/i) { $attrs{'PowerStatusMode'} = 2; }
        elsif ($r =~ /None|3/i)    { $attrs{'PowerStatusMode'} = 3; }
        else { NodeUtils->message('E1', 'EMsgBAD_P_VALUE', 'PowerStatusMode'); }
    }
    if (defined($r = $attrs{'HAMode'}) && !$ENV{'CSM_HAMS_CONTROL'})
      {
	NodeUtils->message('E1', 'EMsgCannotSetHAMode');
      }

    # Build the cmd string
    my $attrstr = '';
    foreach my $k (keys %attrs)
    {
        my $val = $attrs{$k};
        if (!length($val))
        {
            $val = "''";
        }    # mkrsrc-api needs something for the value
        $val =
          NodeUtils->quote($val)
          ;    # Put quotes around the value to protect spaces or weird chars
        $attrstr .= "::${k}::$val";
    }
    my $outref =
      NodeUtils->runrmccmd('chrsrc-api', '-i', qq(-s IBM.DmsCtrl::$attrstr));
}

elsif (
     !defined($::opt_c)) # display all values if not copying binaries, "-c" flag
{
    my $outref =
      NodeUtils->runrmccmd(
                           'lsrsrc-api',
                           "-D ':|:' -n",
                           "-s IBM.DmsCtrl::::'*p0x0020'"
                           );

    # takes the alternating attrs and values and puts them in the hash correctly
    my %attrs = split(/:\|:/, $$outref[0]);

    delete $attrs{'NodeNameList'};        # do not want to display this one
    delete $attrs{'ActivePeerDomain'};    # do not want to display this one
    if ($attrs{'Sensitivity'})
    {
        $attrs{'HeartbeatSensitivity'} = $attrs{'Sensitivity'};
        delete $attrs{'Sensitivity'};
    }
    if ($attrs{'Frequency'})
    {
        $attrs{'HeartbeatFrequency'} = $attrs{'Frequency'};
        delete $attrs{'Frequency'};
    }

    # Give explanations for some of the attributes
    &getMeanings();

    #my %names;
    my $r;    # this reduces the # of hash lookups
    if (defined($r = $attrs{'MaxNumNodesInDomain'}))
    {
        if ($r == -1) { $attrs{'MaxNumNodesInDomain'} .= " $::UNLIMITED"; }
    }
    if (defined($r = $attrs{'AddUnrecognizedNodes'}))
    {
        $attrs{'AddUnrecognizedNodes'} .= $r ? " $::YES" : " $::NO";
    }
    if (defined($r = $attrs{'SetupRemoteShell'}))
    {
        $attrs{'SetupRemoteShell'} .= $r ? " $::YES" : " $::NO";
    }
    if (defined($r = $attrs{'PowerStatusMode'}))
    {
        if ($r =~ /Mixed|0/i)
        {
            $attrs{'PowerStatusMode'} .= " $::MIXED";
        }
        elsif ($r =~ /Events|1/i)
        {
            $attrs{'PowerStatusMode'} .= " $::EVENTS";
        }
        elsif ($r =~ /Polling|2/i)
        {
            $attrs{'PowerStatusMode'} .= " $::POLLING";
        }
        elsif ($r =~ /None|3/i)
        {
            $attrs{'PowerStatusMode'} .= " $::NONE";
        }

    }

    # Now display the rest of the attributes, sorted
    foreach my $k (sort keys %attrs)
    {

        #my $name = defined($names{$k}) ? $names{$k} : $k;
        print " $k = $attrs{$k}\n";
    }
}

#
# Create the /csminstall directory and subdirectories; copy the
# binary files into /csminstall/csm
#
if ($::opt_c)
{
    NodeUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH, 'csminstall',
                              'I', 'IMsgCOPYING_CSMBINARIES');
    InstallUtils->copyBinaries;
    InstallUtils->copy_csm_scripts(1); # copy customization scripts if need
}
elsif (scalar(@ARGV) > 0)
{

    # This handles the case where a customer specifies "csmconfig -L <file> -c"
    foreach my $a (@ARGV)
    {
        if ($a =~ /-c/)
        {
            NodeUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH,
                                      'csminstall', 'I',
                                      'IMsgCOPYING_CSMBINARIES');
            InstallUtils->copyBinaries;
	    InstallUtils->copy_csm_scripts(1); # copy customization scripts if need
        }
    }
}
exit;

# Gets a list of the words: (yes) (no) (on) (off) (unknown)
# and puts them in global vars
sub getMeanings
{

    # Check if we already got them so we do not do it every time.
    if (!defined($::YES))
    {
        ($::YES, $::NO, $::UNLIMITED) =
          split(/\|/, NodeUtils->getMessage('IMsgCsmconfigATTRIBUTE_MEANINGS'));
        ($::MIXED, $::EVENTS, $::POLLING, $::NONE) =
          split(/\|/,
                NodeUtils->getMessage('IMsgCsmconfigPowerATTRIBUTE_MEANINGS'));
    }
}

sub displayLicenseAgreement
{
    my $tab = shift;
    my $rc = InstallUtils->invokeLAP($tab ? 'tab' : 'full');
    if ($rc == 9)
    {

        # Tell the user the license was accepted.
        # a return code of 9 from invokeLAP means
        # that the user accepted it.
        #NodeUtils->msg($::MSGS, 'I', 'EMsgACCEPTED');
        NodeUtils->message('I', 'IMsgACCEPTED');
    }
    else
    {

        # Tell the user the license was not accepted.
        #NodeUtils->msg($::MSGS, 'W3', 'EMsgNOT_ACCEPTED');
        NodeUtils->message('W3', 'EMsgNOT_ACCEPTED');
    }

    # return true or false if the license was accepted or not.
    return ($rc == 9);
}
